package com.teemo.equipment.converter;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import com.teemo.equipment.domain.dto.EquipmentDTO;
import com.teemo.equipment.domain.entity.Equipment;
import com.teemo.equipment.domain.entity.EquipmentRecommend;
import com.teemo.equipment.domain.entity.Hero;
import com.teemo.equipment.domain.entity.RecommendRecord;
import com.teemo.equipment.domain.vo.EquipmentPageVO;
import com.teemo.equipment.domain.vo.RecommendVO;
import com.teemo.equipment.enums.StageEnum;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Teemo
 */
@Mapper
public interface RecommendMapStruct {

    RecommendMapStruct INSTANCE = Mappers.getMapper(RecommendMapStruct.class);

    EquipmentRecommend toEquipmentRecommend(EquipmentDTO dto, Long recommendRecordId);

    default List<EquipmentRecommend> toEquipmentRecommendList(List<EquipmentDTO> equipmentList, Long recommendRecordId) {
        if (CollectionUtil.isEmpty(equipmentList)) {
            return Collections.emptyList();
        }
        return equipmentList.stream().map(dto -> toEquipmentRecommend(dto, recommendRecordId)).collect(Collectors.toList());
    }

    RecommendVO toRecommendVO(RecommendRecord e);

    default RecommendVO getRecommendVO(Map<Long, Equipment> equipmentMap, Map<Long, Hero> heroMap, Map<Long, Map<StageEnum, List<EquipmentRecommend>>> recommendGroup, RecommendRecord e){
        Hero hero = heroMap.getOrDefault(e.getHeroId(), new Hero());
        RecommendVO vo = RecommendMapStruct.INSTANCE.toRecommendVO(e);
        vo.setHeroName(hero.getName());
        vo.setHeroImgId(hero.getImgFileId());
        Map<StageEnum, List<EquipmentRecommend>> stageEnumListMap = recommendGroup.get(e.getId());
        if (MapUtil.isNotEmpty(stageEnumListMap)) {
            List<EquipmentPageVO> outEquipments = Optional.ofNullable(stageEnumListMap.get(StageEnum.OUT_STAGE)).orElse(new ArrayList<>())
                    .stream().map(EquipmentRecommend::getEquipmentId).map(equipmentMap::get)
                    .map(EquipmentMapStruct.INSTANCE::toEquipmentPageVO)
                    .filter(Objects::nonNull).collect(Collectors.toList());
            vo.setOutEquipments(outEquipments);

            List<EquipmentPageVO> coreEquipments = Optional.ofNullable(stageEnumListMap.get(StageEnum.CORE_STAGE)).orElse(new ArrayList<>())
                    .stream().map(EquipmentRecommend::getEquipmentId).map(equipmentMap::get)
                    .map(EquipmentMapStruct.INSTANCE::toEquipmentPageVO)
                    .filter(Objects::nonNull).collect(Collectors.toList());
            vo.setCoreEquipments(coreEquipments);
            List<EquipmentPageVO> godEquipments = Optional.ofNullable(stageEnumListMap.get(StageEnum.GOD_STAGE)).orElse(new ArrayList<>())
                    .stream().map(EquipmentRecommend::getEquipmentId).map(equipmentMap::get)
                    .map(EquipmentMapStruct.INSTANCE::toEquipmentPageVO)
                    .filter(Objects::nonNull).collect(Collectors.toList());
            vo.setGodEquipments(godEquipments);
        }
        return vo;
    }
}
